package com.wuzf.libnetwork;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

public abstract class Request<T> {

    private static Map<String, String> headerEntity = new HashMap<>();
    private static Map<String, Object> paramsEntity = new HashMap<>();

    /**
     * 添加头部
     *
     * @param name
     * @param value
     * @return
     */
    public Request addHeader(String name, String value) {
        headerEntity.put(name, value);
        return this;
    }

    /**
     * 添加参数
     *
     * @param name
     * @param value
     * @return
     */
    public Request addParams(String name, Object value) {
        if (value == null) {
            return this;
        }
        // 需要判断value是否是基本类型
        try {
            if (value.getClass() == String.class) {
                paramsEntity.put(name, value);
            } else {
                Field field = value.getClass().getField("TYPE");
                Class type = (Class) field.get(null);
                if (type.isPrimitive()) {
                    paramsEntity.put(name, value);
                }
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return this;
    }

    public ResultResponse<T> execute() {
        ResultResponse<T> result = null;
        try {
            Response response = getCall().execute();
            result = parseSuccessResponse(response);
        } catch (IOException e) {
            e.printStackTrace();
            result = parseErrorResponse(e);
        }
        return result;
    }


    public void execute(JsonCallBack callBack) {
        // 通过okHttp的call进行查询
        getCall().enqueue(new Callback() {

            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                callBack.onError(parseErrorResponse(e));
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                callBack.onSuccess(parseSuccessResponse(response));
            }
        });
    }

    public static Map<String, Object> getParamsEntity() {
        return paramsEntity;
    }

    protected abstract okhttp3.Request generateRequest(okhttp3.Request.Builder builder);

    private void addHeader(okhttp3.Request.Builder builder) {
        if (headerEntity.size() == 0) {
            return;
        }
        for (Map.Entry<String, String> entry : headerEntity.entrySet()) {
            builder.addHeader(entry.getKey(), entry.getValue());
        }
    }

    private Call getCall() {
        okhttp3.Request.Builder builder = new okhttp3.Request.Builder();
        addHeader(builder);
        okhttp3.Request request = generateRequest(builder);
        return ApiService.httpClient.newCall(request);
    }

    private ResultResponse<T> parseErrorResponse(@NotNull IOException e) {
        ResultResponse<T> resultResponse = new ResultResponse<>();
        resultResponse.setMessage(e.getMessage());
        return resultResponse;
    }

    private <T> ResultResponse<T> parseSuccessResponse(Response response) throws IOException {
        boolean success = response.isSuccessful();
        int code = response.code();
        String content = response.body().string();
        System.out.println("content:" + content);
        T body = JSON.parseObject(content, new TypeReference<T>() {
        });
        return new ResultResponse(success, code, "success", body);
    }
}
